#include "path.h"
#include <stdlib.h>
#include <string.h>

fs_ret_t fs_cutPathHead(char* path, char * head){
	uint32_t pathLen = strlen(path);
	uint32_t curPos = pathLen-1;
	// Case ""
	if(!pathLen) return ERR_PARAMETER_PROBLEM;
	// removing the last '/' in "***/**/"
	if(path[pathLen-1]=='/'){
		path[pathLen-1] = '\0';
		--pathLen;
	}
	// Case previously "/"
	if(!pathLen) return ERR_PARAMETER_PROBLEM;
	// Main loop.
	while(curPos>0 && path[curPos]!='/') --curPos;
	// If not, there is just a folder name.
	if(path[curPos] == '/'){
		path[curPos] = '\0';
		if(head){
			// Can't handle this case.
			if(!strcmp(".",path+curPos+1)||!strcmp("..",path+curPos+1)){
				return ERR_PARAMETER_PROBLEM;
			}
			strcpy(head,path+curPos+1);
		}
	}else{// If not, there is just an item name.
		strcpy(head,path);
		path[curPos] = '\0';
	}
	return RET_NO_PROBLEM;
}

fs_ret_t fs_getItemInFolderbyName(FileSystemHandle_t *fsh,inodeid_t folder,const char* itemToGet,inodeid_t *finalPos){
	char* itemName = malloc(257);
	fs_ret_t ret = RET_NO_PROBLEM;
	filepos_t cursor = 0;
	do{
		ret = fs_getNextFolderItem(fsh,folder,&cursor,itemName,finalPos);
		if(ret) goto cleanup;
	}while(strcmp(itemToGet,itemName));
	// finalPos is already set.
	cleanup:
	if(ret==ERR_OUT_OF_RANGE){
		ret = ERR_NOT_FOUND;
		DEBUG_PRINT("Item not found in %d : \"%s\"\n",folder,itemToGet)
	}
	free(itemName);
	return ret;
}

fs_ret_t fs_solvePath(FileSystemHandle_t *fsh,inodeid_t startPos,const char* pathToSolve,inodeid_t *containingFolder,inodeid_t *finalPos){
	fs_ret_t ret = RET_NO_PROBLEM;
	char *currentToken = malloc(257);
	if(pathToSolve[0]=='/'){// Absolute path.
		startPos = fsh->fsd.fsRoot;
		if(containingFolder) *containingFolder = fsh->fsd.fsRoot;// Maybe change this behaviour.
		++pathToSolve;
	}
	// Handling the "" case
	*finalPos = startPos;
	while(pathToSolve[0]!='\0'){
		uint16_t posInToken = 0;
		// Getting one item of the path.
		/// \todo check for forbiden chars.
		while(posInToken<256 && *pathToSolve!='/' && *pathToSolve!='\0'){
			currentToken[posInToken] = *pathToSolve;
			++posInToken;
			++pathToSolve;
		}
		if(posInToken==256){
			ret = ERR_PATH_MALFORMATED;
			goto cleanup;
		}
		if(posInToken==0){
			if(*pathToSolve=='/'){// case "foo//bar"
				ret = ERR_PATH_MALFORMATED;
				goto cleanup;
			}else{// case "foo/bar/", btw should test if last item is folder.
				goto cleanup;
			}
		}
		currentToken[posInToken] = '\0';
		if(*pathToSolve!='\0') ++pathToSolve;// Skipping the item separator.
		if(containingFolder) *containingFolder = startPos;
		// Now searching it in current folder.
		ret = fs_getItemInFolderbyName(fsh,startPos,currentToken,finalPos);
		if(ret){
			goto cleanup;
		}
		// Next folder.
		startPos = *finalPos;
	}
	// last dir could be ".." or ".", or path could be empty.
	if(containingFolder && fs_assertInodeIsFolder(fsh,*finalPos)){
		fs_getItemInFolderbyName(fsh,*finalPos,"..",containingFolder);
	}
	cleanup:
	free(currentToken);
	return ret;
}
